package myJs.common.produceQrCode

import myJs.CpLayer
import myJs.Implicits._
import myJs.api.Api
import myJs.common.InputInlineCp
import myJs.cps.BootstrapTableCp.Column
import myJs.cps.Style
import myJs.cps.project.QrcodeCp
import myJs.myPkg._
import myJs.tool.Pojo._
import myJs.tool.Tool
import slinky.core.FunctionalComponent
import slinky.core.annotations.react
import slinky.core.facade.Hooks.{useEffect, useState}
import slinky.web.html._

import scala.collection.immutable.SeqMap
import scala.scalajs.js
import myJs.myPkg.jquery._
import myJs.myPkg.reactHookForm._
import org.scalajs.dom
import org.scalajs.dom.{Blob, BlobPropertyBag, Element, HTMLImageElement, document, html, window}
import org.scalajs.dom.html.Canvas
import slinky.core.facade.React

import scala.scalajs.js.JSConverters._
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import shared.pojo.Pojo
import slinky.web.SyntheticMouseEvent
import upickle.default._
import typings.csstype.csstypeStrings

import scala.concurrent.Future
import scala.scalajs.js.JSON

/**
 * Created by yz on 21/1/2022
 */
@react object Cp {

  type Props = Unit

  type Ctx2D = dom.CanvasRenderingContext2D

  val curPage = ProduceQrcode

  val component = FunctionalComponent[Props] { props =>

    val (ids, setIds) = useState(List.empty[String])
    val (num, setNum) = useState("1")

    val useForm = ReactHookForm.useForm(UseFormOptions(mode = "onChange"))

    object FTool {

      def refreshQrcode = () => {
        import Pojo.sampleId._
        val index = layer.alert(Tool.myElement, Tool.layerOptions)
        val request = GetNewIds.Request(num = num.toInt, account = Tool.getAccount)
        Api.sampleId.getNewIds(request).map { newIds =>
          setIds(newIds)
          layer.close(index)
        }
        $("#result").show()
        ()
      }

      def downloadQrcode = () => {
        val zip = new JSZip()
        val es = $(".qrcodeBox .img").es
        val dataFs = es.map { y =>
          val id = $(y).find("p").text().trim.replaceAll("^PN:", "")
          DomToImage.toPng(y).toFuture.map { url =>
            ImageData(id = id, url = url)
          }
        }
        Future.sequence(dataFs).map { datas =>
          datas.foreach { data =>
            val id = data.id
            val fileName = s"${id}.png"
            val imageData = data.url.replaceAll("^data:image/png;base64,", "")
            zip.file(fileName, imageData, JSZipOptions(base64 = true))
          }
          zip.generateAsync(GenerateOptions(`type` = "blob")).toFuture.foreach { content =>
            FileSaver.saveAs(content, s"qrcode_${es.size}.zip")
          }
        }
        ()
      }

      def createTempNode = {
        $("#prepare_print_block").html($("#show_qrcode_body").html())
        $("#prepare_print_block").find(".qrcodeBox .print-download-btns-parent").remove()
      }

      def printAll = () => {
        createTempNode
        Tool.printClick
        ()
      }

      def numChange = (v: String) => {
        setNum(v)
      }

      def formSubmit = useForm.handleSubmit((data: js.Dictionary[js.Any]) => {
        println(JSON.stringify(data))
        FTool.refreshQrcode()
      })

    }

    CpLayer(title = curPage.titleStr)(
      div(className := "page-content",
        div(className := "row-fluid",
          div(className := "row",
            div(className := "col-md-12 col-sm-12",
              div(className := "portlet light",
                div(className := "portlet-title",
                  div(className := "caption", s"${curPage.titleStr}")
                ),
                div(className := "portlet-body",

                  form(className := "form-horizontal", onSubmit := FTool.formSubmit,

                    InputInlineCp(useForm = useForm, label = "数量", name = "num", labelWidth = 2, inputWidth = 4,
                      value = num,
                      onChange = FTool.numChange, registerOptions = {
                        val info = "数量"
                        RegisterOptions(
                          required = ValidationValueMessage(value = true, message = s"${info}不能为空!"),
                          pattern = ValidationValueMessage(value = Tool.integerRegexp, message = s"${info}必须为整数"),
                          validate = Tool.betweenValidate(1, 50, info)
                        )
                      }),

                    div(className := "form-group",
                      div(className := "actions col-sm-offset-2 col-sm-2",
                        button(`type` := "submit", className := "btn btn-primary",
                          i(className := "fa fa-plus"),
                          s" 生成二维码",
                        ),
                      )
                    ),

                  ),

                  div(id := "result", style := Style(display = csstypeStrings.none),
                    hr(),
                    div(id := "download", style := Style(marginTop = "20px"),
                      button(className := "btn btn-primary", data - "value" := "ko_dodge.png",
                        onClick := FTool.downloadQrcode,
                        style := Style(marginLeft = "15px"),
                        i(className := "fa fa-download"),
                        s" 全部下载",
                      ),
                      button(className := "btn btn-primary", data - "value" := "ko_dodge.png",
                        onClick := FTool.printAll,
                        style := Style(marginLeft = "15px"),
                        i(className := "fa fa-print"),
                        s" 全部打印",
                      )
                    ),
                    div(id := "qrcodeResult", style := Style(display = csstypeStrings.flex, flexWrap = csstypeStrings.wrap,
                      justifyContent = csstypeStrings.left),
                      div(id := "show_qrcode_body", style := Style(display = csstypeStrings.flex),
                        ids.zipWithIndex.map { case (idStr, curI) =>
                          QrcodeCp(key = s"${curI}", sampleId = idStr)
                        }
                      ),
                      div(style := Style(width = "1px", height = "1px", overflow = "hidden",
                        position = csstypeStrings.relative,
                        backgroundColor = "#fff"),
                        div(style := Style(position = csstypeStrings.absolute, right = "300px"),
                          ul(id := "prepare_print_block")
                        )
                      )
                    )
                  )

                ),
              )
            )
          )
        )
      )
    )

  }


}
